/**
 * 服务器监控界面。
 * TODO: 当该界面隐藏后再显示时，图表x轴和y轴显示不正常，格式丢失。
 * @author linzongxue
 * @create_date 2011-12-22
 */
define(function(){
	var interval = 3; //性能数据刷新时间间隔（单位:秒）
	var maxPoint = 25; //图表上的最大点数
	var charHeight = 180;
	
	var perfDataStoreType = Ext.data.Record.create(['time', 
 		'heapMemUsed', 'heapMemInit', 'heapMemCommitted', 'heapMemMax', 
 		'nonHeapMemUsed', 'nonHeapMemMax',
 	    'liveThreadCount', 'peakThreadCount', 'totalThreadCount',
 	    'loadedClassCount', 'unoadedClassCount', 'totalLoadedClassCount',
 	    'osLoadAverage','osFreePhysicalMem',
 	    'jvmCpuUsage', 'jvmUptime', 'jvmCpuTime'
	]);
	//格式
	var formatMem = function(size, prec){
		size = size/1024/1024;
		var f = '0,0';
		if (prec && /^\d+$/.test(prec)){
			size = size.toFixed(prec);
			f = f + '.' + new Array(prec + 1).join('0');
		}
		return Ext.util.Format.number(size, f) + ' MB';
	}
	
	var ServerMonitorPanel = Ext.extend(Ext.Panel, {
        title: '服务器监控',
        layout: 'column',
        autoScroll: true,
        defaults: {border:false},
        perfDataStore: new Ext.data.JsonStore(), //存放图表中的性能数据 
        chartBbarStyle: 'background:#fff;border:none;', //图表底部栏的样式
        tbar: [{xtype:'label', text:'服务器监控信息，最后更新时间:', style:'margin-left:5px;'}, {xtype:'label', id:'updateTime'}],
        initComponent: function(){
        	this.items = [{
    	    	layout: 'anchor',
    	    	columnWidth: 1,
    	        padding: '5',
    	    	items:[
       	    	    this.jvmHeapPanel = this.createJvmHeapPanel(),
       	    	    this.jvmCpuPanel = this.createJvmCpuPanel(),
       	    		this.jvmThreadPanel = this.createJvmThreadPanel(),
       	    		this.jvmClassPanel = this.createJvmClassPanel()
    	    	]
    	    },{
    	    	layout: 'anchor',
    	    	width: 280,
    	        split: true,
    	        padding: '5',
    	    	items:[
	    	    	this.jvmDescGrid = this.createJvmDescGrid(),
	    	    	{height:10, border:false},
    	    	    this.osDescGrid = this.createOsDescGrid()
    	    	]
    	    }];
        	ServerMonitorPanel.superclass.initComponent.call(this);
        	this.on('afterrender', function(){
            	this.initServerDesc();
            	this.schedule();
        	});
        	this.on('activate', function(){
        		//看能否解决图表x,y轴的标题显示问题
        	});
        },
        //获取服务器描述信息
        initServerDesc: function(){
        	cu.get({
        		url:'sys/util/getServerOsDesc.do',
        		success: function(data){
	        		data.totalPhysicalMem = formatMem(data.totalPhysicalMem);
	        		this.osDescGrid.setSource(data);
	        	}, 
	        	scope: this
        	});
        	cu.get({
        		url: 'sys/util/getServerJvmDesc.do',
        		success: function(data){
	        		data.startTime = new Date(data.startTime).format('Y-m-d H:i:s');
	        		this.jvmDescGrid.setSource(data);
	        	}, 
	        	scope: this
        	});
        },
        //定时刷新性能数据
        schedule: function(){
        	var me = this;
        	var updateData = function(){
        		if (!me.isVisible()) return;
        		cu.get({
        			url: 'sys/util/getServerPerfData.do',
        			waitMsg: null,
        			success: function(data){
	    				if (!data) return;
	    				this.updatePerfData(data);
	    				this.updateDynamicData(data);
	    			},
	    			scope: me
        		});
        	}
        	updateData();
        	var intervalHandler = setInterval(updateData, interval * 1000);
        	this.on('destroy', function(){
        		clearInterval(intervalHandler);
        	});
        },
        //更新性能数据，图表自动更新
        updatePerfData: function(data){
        	this.perfDataStore.add(new perfDataStoreType(data));
			if (this.perfDataStore.getCount() > maxPoint){
				this.perfDataStore.removeAt(0);
			}
        },
        //更新动态显示的数据，如更新时间，jvm运行时间等
        updateDynamicData: function(data){
			this.getTopToolbar().get('updateTime').setText(new Date(data.time).format('Y-m-d H:i:s'));
			this.jvmHeapPanel.updateBbar(data);
			this.jvmThreadPanel.updateBbar(data);
			this.jvmClassPanel.updateBbar(data);
			this.jvmCpuPanel.updateBbar(data);
			this.osDescGrid.updateDynamicData(data);
			this.jvmDescGrid.updateDynamicData(data);
        },
        createOsDescGrid: function(){
            return new Ext.grid.PropertyGrid({  
                title: '操作系统信息',  
                height: 250,
	   	 		stripeRows: false,
	   		    enableHdMenu: false,
	   		    disableSorting: true, //禁用自动排序，需要重写PropertyGrid的initComponent方法
	   		    propertyNames:{
	   		    	name: '系统名称', 
	   		    	arch: '系统架构', 
	   		    	version: '系统版本', 
	   		    	processorCount: '处理器个数', 
	   		    	totalPhysicalMem: '物理内存总量',
	   		    	osFreePhysicalMem: '物理内存剩余量',
	   		    	osTotalSwapSpace: '虚拟内存总量',
	   		    	osFreeSwapSpace: '虚拟内存剩余量'
	   		    },
                listeners:{
                	beforeedit: function(e){e.cancel = true; return false},
                	render: function(){this.getColumnModel().setColumnWidth(0, 110);}
                },
                updateDynamicData: function(data){
                	this.setProperty('osFreePhysicalMem', formatMem(data.osFreePhysicalMem), true);
                	this.setProperty('osTotalSwapSpace', formatMem(data.osTotalSwapSpace), true);
                	this.setProperty('osFreeSwapSpace', formatMem(data.osFreeSwapSpace), true);
                }
            });
        },
        createJvmDescGrid: function(){
            return new Ext.grid.PropertyGrid({  
                title: '虚拟机(JVM)信息',  
                height: 340,
	   	 		stripeRows: false,
	   		    enableHdMenu: false,
	   		    disableSorting: true,
	   		    propertyNames:{
	   		    	jreVersion: 'JRE版本',
	   		    	jitCompiler: 'JIT编译器', 
	   		    	name: '虚拟机名称', 
	   		    	vendor: '虚拟机供应商', 
	   		    	version: '虚拟机版本',
	   		    	runtimeName: '运行名称',
	   		    	startTime: '启动时间',
	   		    	jvmUptime: '正常运行时长',
	   		    	jvmCpuTime: '占用CPU总时长',
	   		    	jvmCpuUsage: '占用CPU比率',
	   		    	heapMem: '堆内存(已用/总量)',
	   		    	nonHeapMem: '非堆内存(已用/总量)'
	   		    },
                listeners:{
                	beforeedit: function(e){e.cancel = true; return false},
                	render: function(){this.getColumnModel().setColumnWidth(0, 110);}
                },
                updateDynamicData: function(data){
                	this.setProperty('jvmUptime', lu.formatSeconds((data.jvmUptime/1000).toFixed(0)), true);
                	this.setProperty('jvmCpuTime', lu.formatSeconds((data.jvmCpuTime/1000000000).toFixed(2)), true);
                	this.setProperty('jvmCpuUsage', (data.jvmCpuUsage * 100).toFixed(1) + '%', true);
                	this.setProperty('heapMem', formatMem(data.heapMemUsed, 1) + ' / ' + formatMem(data.heapMemMax, 1), true);
                	this.setProperty('nonHeapMem', formatMem(data.nonHeapMemUsed, 1) + ' / ' + formatMem(data.nonHeapMemMax, 1), true);
                }
            });
        },
   	    createJvmHeapPanel: function(){
   	    	return new Ext.form.FieldSet({
   	    		title: 'JVM堆内存',
   	    		height: charHeight,
   	    		collapsible: false, //不能收缩，会报错
   	    		layout: 'form',
   	    		items:{
   	    			//组件隐藏后再显示时，xAixis和yAixis的render方法不会重新生效
   	                xtype: 'linechart',
   	                store: this.perfDataStore,
   	                xField: 'time',
   	                yField: 'heapMemUsed',
   	                xAxis: new Ext.chart.TimeAxis({
   	                	labelSpacing: 20,
   	                    labelRenderer:Ext.util.Format.dateRenderer('H:i:s'),
   	                    hideOverlappingLabels: true
   	                }),
   	                yAxis: new Ext.chart.NumericAxis({
   	                    labelRenderer : function(value){return formatMem(value);}
   	                })
   	            },
   	            bbar:{
   	            	buttonAlign: 'center',
   	            	style: this.chartBbarStyle,
   	            	items: [
	   	                {xtype:'label', text:'已使用:', style:'color:blue;font-weight:bold;'},
	   	                {xtype:'label', id: 'heapMemUsed', style: 'margin-right:10px;color:blue;font-weight:bold;'},
	   	                {xtype:'label', text:'已提交:'},
	   	                {xtype:'label', id: 'heapMemCommitted', style: 'margin-right:10px;'},
	   	                {xtype:'label', text:'初始值:'},
	   	                {xtype:'label', id: 'heapMemInit', style: 'margin-right:10px;'},
	   	                {xtype:'label', text:'最大值:'},{xtype:'label', id: 'heapMemMax'}
   	            ]},
   	            updateBbar: function(data){
   	            	var me = this;
   	            	var bbar = this.getBottomToolbar();
   	            	var setText = function(attr){
   	            		bbar.get(attr).setText(formatMem(data[attr], 1));
   	            	};
   	            	setText('heapMemUsed');
   	            	setText('heapMemCommitted');
   	            	setText('heapMemInit');
   	            	setText('heapMemMax');
   	            }
   	    	});
   	    },
		createJvmCpuPanel: function(){
   	    	return new Ext.form.FieldSet({
   	    		title: 'JVM占用CPU比率',
   	    		height: charHeight,
   	    		collapsible: false,
   	    		layout: 'form',
   	    		items:{
   	                xtype: 'linechart',
   	                store: this.perfDataStore,
   	                xField: 'time',
   	                yField: 'jvmCpuUsage',
   	                xAxis: new Ext.chart.TimeAxis({
   	                	labelSpacing: 20,
   	                    labelRenderer:Ext.util.Format.dateRenderer('H:i:s'),
   	                    hideOverlappingLabels: true
   	                }),
   	                yAxis: new Ext.chart.NumericAxis({
   	                    labelRenderer : function(value){return (value * 100).toFixed(1) + '%'}
   	                })
   	            },
   	            bbar:{
   	            	buttonAlign: 'center',
   	            	style: this.chartBbarStyle,
   	            	items: [
     	                {xtype:'label', text:'占用CPU比率:', style:'color:blue;font-weight:bold;'},
     	                {xtype:'label', id: 'jvmCpuUsage', style: 'color:blue;font-weight:bold;'}
   	            ]},
   	            updateBbar: function(data){
   	            	this.getBottomToolbar().get('jvmCpuUsage').setText((data.jvmCpuUsage * 100).toFixed(1) + '%');
   	            }
   	    	});
		},
   	    createJvmThreadPanel: function(){
   	    	return new Ext.form.FieldSet({
   	    		title: 'JVM线程数量',
   	    		height: charHeight,
   	    		collapsible: false,
   	    		layout: 'form',
   	    		items:{
   	                xtype: 'linechart',
   	                store: this.perfDataStore,
   	                xField: 'time',
   	                yField: 'liveThreadCount',
   	                xAxis: new Ext.chart.TimeAxis({
   	                	labelSpacing: 20,
   	                    labelRenderer:Ext.util.Format.dateRenderer('H:i:s'),
   	                    hideOverlappingLabels: true
   	                }),
   	                yAxis: new Ext.chart.NumericAxis({
   	                    labelRenderer : Ext.util.Format.numberRenderer('0,0')
   	                })
   	            },
   	            bbar:{
   	            	buttonAlign: 'center',
   	            	style: this.chartBbarStyle,
   	            	items: [
     	                {xtype:'label', text:'活动:', style:'color:blue;font-weight:bold;'},
     	                {xtype:'label', id: 'liveThreadCount', style: 'margin-right:10px;color:blue;font-weight:bold;'},
       	                {xtype:'label', text:'峰值:'},
       	                {xtype:'label', id: 'peakThreadCount', style: 'margin-right:10px;'},
       	                {xtype:'label', text:'总数:'},
       	                {xtype:'label', id: 'totalThreadCount'}
   	            ]},
   	            updateBbar: function(data){
   	            	this.getBottomToolbar().get('liveThreadCount').setText(data.liveThreadCount);
   	            	this.getBottomToolbar().get('peakThreadCount').setText(data.peakThreadCount);
   	            	this.getBottomToolbar().get('totalThreadCount').setText(data.totalThreadCount);
   	            }
   	    	});
   	    },
   	    createJvmClassPanel: function(){
   	    	return new Ext.form.FieldSet({
   	    		title: 'JVM加载类数量',
   	    		height: charHeight,
   	    		collapsible: false,
   	    		layout: 'form',
   	    		items:{
   	                xtype: 'linechart',
   	                store: this.perfDataStore,
   	                xField: 'time',
   	                yField: 'loadedClassCount',
   	                xAxis: new Ext.chart.TimeAxis({
   	                	labelSpacing: 20,
   	                    labelRenderer:Ext.util.Format.dateRenderer('H:i:s'),
   	                    hideOverlappingLabels: true
   	                }),
   	                yAxis: new Ext.chart.NumericAxis({
   	                    labelRenderer : Ext.util.Format.numberRenderer('0,0')
   	                })
   	            },
   	            bbar:{
   	            	buttonAlign: 'center',
   	            	style: this.chartBbarStyle,
   	            	items: [
     	                {xtype:'label', text:'已加载:', style:'color:blue;font-weight:bold;'},
     	                {xtype:'label', id: 'loadedClassCount', style: 'margin-right:10px;color:blue;font-weight:bold;'},
       	                {xtype:'label', text:'已卸载:'},
       	                {xtype:'label', id: 'unoadedClassCount', style: 'margin-right:10px;'},
       	                {xtype:'label', text:'总计:'},
       	                {xtype:'label', id: 'totalLoadedClassCount'}
   	            ]},
   	            updateBbar: function(data){
   	            	var bbar = this.getBottomToolbar();
   	            	var setText = function(attr){
   	            		bbar.get(attr).setText(Ext.util.Format.number(data[attr], '0,0')); return this;
   	            	};
   	            	setText('loadedClassCount');
   	            	setText('unoadedClassCount');
   	            	setText('totalLoadedClassCount');
   	            }
   	    	});
		}
	});
	
	return ServerMonitorPanel;
});